(function () {
    "use strict";

    var defineType = require("./define-type");
    var DocumentNode = require("./document-node");

    var Block = defineType(new DocumentNode(0, 0), {
        position: {
            x: 0,
            y: 0
        },
        size: {
            width: 0,
            height: 0,
        },
        zIndex: 0
    });

    var TextBlock = defineType(new Block(0, 0), {
        text: ""
    });

    var ImageBlock = defineType(new Block(0, 0), {
        image: ""
    });

    var Layout = defineType(function () {
        this.freeze(true);
        this.blocks = new DocumentNode.List;
        this.freeze(false);
    }, new DocumentNode(0, 0), {
        template: null,
        blocks: null,

        jsonOptions: {
            template: {
                nodeType: Layout,
                idOnly: true
            },
            blocks: {
                list: true,
                getNodeType: function (json) {
                    return "image" in json ? ImageBlock : TextBlock;
                }
            }
        },

        isTemplateOf: function (template) {
            return isTemplateOf(this, template);
        },

        template_change: function (e) {
            if (this.isTemplateOf(e.newValue)) {
                throw new Error("circular templates not allowed");
            }
        }
    });

    function isTemplateOf(layout, template) {
        if (!template) {
            return false;
        }

        if (layout === template) {
            return true;
        }

        return isTemplateOf(layout, template.template);
    };

    var Document = defineType(function () {
        this.freeze(true);
        this.templates = new DocumentNode.List;
        this.pages = new DocumentNode.List;
        this.freeze(false);
    }, new DocumentNode(0, 0), {
        jsonOptions: {
            documentTemplate: {
                nodeType: Layout,
                idOnly: true
            },
            templates: {
                list: true,
                nodeType: Layout
            },
            pages: {
                list: true,
                nodeType: Layout
            }
        },
        documentTemplate: null,
        templates: null,
        pages: null
    });

    module.exports.Block = Block;
    module.exports.TextBlock = TextBlock;
    module.exports.ImageBlock = ImageBlock;
    module.exports.Layout = Layout;
    module.exports.Document = Document;
    module.exports.isTemplateOf = isTemplateOf;
})();
